#include "widget.h"
#include "ui_widget.h"
#include "qdebug.h"
#include "QTime"
#include "QFileDialog"
#include "QPushButton"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //创建libVLC实例
    m_vlcBase = libvlc_new(0, NULL);
    Q_ASSERT(m_vlcBase);

    //初始化速率选择comboBox控件
    initSpeedComboBox();
}

Widget::~Widget()
{
    // 1. 停止播放并解除事件监听
    if (m_vlcMediaPlayer) {
        // 异步停止播放（避免阻塞）
        if (libvlc_media_player_is_playing(m_vlcMediaPlayer)){
            libvlc_media_player_stop(m_vlcMediaPlayer);
        }
        // 解除事件监听
        libvlc_event_manager_t* em = libvlc_media_player_event_manager(m_vlcMediaPlayer);
        libvlc_event_detach(em, libvlc_MediaPlayerTimeChanged, &Widget::vlcEvents, this);
        libvlc_event_detach(em, libvlc_MediaPlayerEndReached, &Widget::vlcEvents, this);
        libvlc_event_detach(em, libvlc_MediaPlayerStopped, &Widget::vlcEvents, this);
        libvlc_event_detach(em, libvlc_MediaPlayerPlaying, &Widget::vlcEvents, this);
        libvlc_event_detach(em, libvlc_MediaPlayerPaused, &Widget::vlcEvents, this);

        // 解除Media引用和清除HWND绑定
        libvlc_media_player_set_hwnd(m_vlcMediaPlayer, nullptr);
        libvlc_media_player_set_media(m_vlcMediaPlayer, nullptr);

        // 释放播放器
        libvlc_media_player_release(m_vlcMediaPlayer);
        m_vlcMediaPlayer = nullptr;
    }

    // 2. 释放Media
    if (m_vlcMedia) {
        libvlc_media_release(m_vlcMedia);
        m_vlcMedia = nullptr;
    }

    // 3. 最后释放libVLC实例
    if (m_vlcBase) {
        libvlc_release(m_vlcBase);
        m_vlcBase = nullptr;
    }

    // 4. 删除UI（确保所有资源已释放）
    delete ui;
}

void Widget::onVlcMediaPlayerPlaying()
{
    if (m_vlcMediaPlayer)
    {
        libvlc_time_t duration = libvlc_media_player_get_length(m_vlcMediaPlayer);

        QTime time = QTime(0, 0, 0).addMSecs(duration);
        QString strTime = time.toString("mm:ss");
        ui->labelEndTime->setText(strTime);

        ui->horizontalSliderPlayer->setMaximum(duration / 1000);
    }
}

void Widget::onVlcMediaPlayerTimeChanged()
{
    if (m_vlcMediaPlayer)
    {
        libvlc_time_t curTime = libvlc_media_player_get_time(m_vlcMediaPlayer);

        QTime time = QTime(0, 0, 0).addMSecs(curTime);
        QString strTime = time.toString("mm:ss");
        ui->labelStartTime->setText(strTime);

        ui->horizontalSliderPlayer->blockSignals(true);
        ui->horizontalSliderPlayer->setValue(curTime / 1000);
        ui->horizontalSliderPlayer->blockSignals(false);
    }
}


void Widget::onVlcMediaPlayerEndReached()
{
    if (m_vlcMediaPlayer)
    {
        ui->horizontalSliderPlayer->setValue(0);

        ui->labelStartTime->setText("--:--");
        ui->labelEndTime->setText("--:--");
    }
}

void Widget::onVlcMediaPlayerStopped()
{
    if (m_vlcMediaPlayer)
    {
        ui->horizontalSliderPlayer->setValue(0);
        ui->labelStartTime->setText("--:--");
        ui->labelEndTime->setText("--:--");
    }
}


void Widget::on_btnOpen_clicked()
{
    //释放之前播放器
    if (m_vlcMediaPlayer) {
        if (libvlc_media_player_is_playing(m_vlcMediaPlayer)){
            libvlc_media_player_stop(m_vlcMediaPlayer);
        }

        libvlc_media_player_release(m_vlcMediaPlayer);
        m_vlcMediaPlayer = nullptr;
    }

    if (m_vlcMedia) {
        libvlc_media_release(m_vlcMedia);
        m_vlcMedia = nullptr;
    }

    //选择播放文件
    QString fileName = QFileDialog::getOpenFileName(this, "选择打开的文件", "", "*.*");
    if (fileName.isEmpty()) {
        return;
    }

    fileName = QDir::toNativeSeparators(fileName);

    //创建播放器
    m_vlcMedia = libvlc_media_new_path(m_vlcBase, fileName.toUtf8().data());
    if (!m_vlcMedia) {
        return;
    }

    m_vlcMediaPlayer = libvlc_media_player_new_from_media(m_vlcMedia);
    if (!m_vlcMediaPlayer) {
        libvlc_media_release(m_vlcMedia);
        m_vlcMedia = nullptr;
        return;
    }

    // 设置解析标志（必须！否则无法触发ParsedChanged事件）
//    libvlc_media_parse_with_options(m_vlcMedia, libvlc_media_parse_local, -1);

    //解析媒体文件取元数据（时长、编码格式、分辨率等,异步操作，解析完成后会触发 libvlc_MediaParsedChanged 事件
    libvlc_media_parse(m_vlcMedia);

    libvlc_event_manager_t* media_em = libvlc_media_event_manager(m_vlcMedia); // 获取媒体事件管理器（注意：不是media_player的事件管理器！）
    if(libvlc_event_attach(media_em, libvlc_MediaParsedChanged, &Widget::vlcMediaEvents, this))
    {
        qDebug() << "libvlc_event_attach failed.";
    }else {
        qDebug() << "libvlc_event_attach success.";
    }

    // 监听播放器事件
    libvlc_event_manager_t* em = libvlc_media_player_event_manager(m_vlcMediaPlayer);
    libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, &Widget::vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerEndReached, &Widget::vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerStopped, &Widget::vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerPlaying, &Widget::vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerPaused, &Widget::vlcEvents, this);

    //  绑定到 Qt 控件，确保画面显示, windows下ui->widgetRender->winId()返回控件的原生窗口句柄HWND
    libvlc_media_player_set_hwnd(m_vlcMediaPlayer, (void*)ui->widgetRender->winId());

    //禁用VLC鼠标、键盘事件  VLC默认接管鼠标键盘事件，禁用后才能在QWidget中获取鼠标、键盘事件
    libvlc_video_set_mouse_input(m_vlcMediaPlayer, 0);
    libvlc_video_set_key_input(m_vlcMediaPlayer, 0);

    //设置视频播放速率
    double speed = ui->comboBoxRate->itemData(m_defaultIndex).toDouble();
    if (m_vlcMediaPlayer) {
        libvlc_media_player_set_rate(m_vlcMediaPlayer, speed);
    }
}

void Widget::on_btnPlay_clicked()
{
    if (m_vlcMediaPlayer) {
        if (libvlc_media_player_is_playing(m_vlcMediaPlayer)) {
            libvlc_media_player_pause(m_vlcMediaPlayer);
            ui->btnPlay->setText("播放");
        }else{
            setVideoAspectRatio(false);
            libvlc_media_player_play(m_vlcMediaPlayer);
            ui->btnPlay->setText("暂停");
        }
    }
}

void Widget::on_btnStop_clicked()
{
    if (m_vlcMediaPlayer) {
        libvlc_media_player_stop(m_vlcMediaPlayer);
    }

    ui->btnPlay->setText("播放");
}

void Widget::on_horizontalSliderPlayer_valueChanged(int value)
{
    if (m_vlcMediaPlayer)
    {
        libvlc_time_t time = value * 1000.0;
        libvlc_media_player_set_time(m_vlcMediaPlayer, time);
    }
}

void Widget::resizeEvent(QResizeEvent* event)
{
    setVideoAspectRatio(false);

    QWidget::resizeEvent(event);
}

void Widget::mouseDoubleClickEvent(QMouseEvent* event)
{
    if (this->isFullScreen())
    {
        this->showNormal();
    }
    else
    {
        this->showFullScreen();
    }

    ui->widgetTools->setVisible(!this->isFullScreen());

    QWidget::mouseDoubleClickEvent(event);
}

void Widget::vlcEvents(const libvlc_event_t* ev, void* param)
{
    Widget* vlcPlayer = reinterpret_cast<Widget*>(param);
    if (!vlcPlayer) {
        return;
    }

    switch (ev->type)
    {
    case libvlc_MediaPlayerTimeChanged:
        QMetaObject::invokeMethod(vlcPlayer, "onVlcMediaPlayerTimeChanged", Qt::QueuedConnection);
        break;

    case libvlc_MediaPlayerEndReached:
        QMetaObject::invokeMethod(vlcPlayer, "onVlcMediaPlayerEndReached", Qt::QueuedConnection);
        break;

    case libvlc_MediaPlayerStopped:
        QMetaObject::invokeMethod(vlcPlayer, "onVlcMediaPlayerStopped", Qt::QueuedConnection);
        break;

    case libvlc_MediaPlayerPlaying:
        QMetaObject::invokeMethod(vlcPlayer, "onVlcMediaPlayerPlaying", Qt::QueuedConnection);
        break;

    case libvlc_MediaPlayerPaused:
        qDebug() << "vlc media player paused event called.";
        break;

    default:
        break;
    }
}

// 静态回调函数（处理媒体事件）
void Widget::vlcMediaEvents(const libvlc_event_t* event, void* userData) {
    Widget* vlcPlayer = static_cast<Widget*>(userData);

    qDebug() << "vlcMediaEvents 1111";

    switch (event->type) {
        case libvlc_MediaParsedChanged: {
            QMetaObject::invokeMethod(vlcPlayer, "showMediaMetadata", Qt::QueuedConnection);

//            if (libvlc_media_is_parsed(vlcPlayer->m_vlcMedia)) {
//                // 解析完成，获取元数据
//                qDebug() << "元数据解析成功";
//                vlcPlayer->showMediaMetadata();
//            } else {
//                qDebug() << "元数据解析失败";
//            }
            break;
        }
    }
}

// 成员函数：提取并展示元数据
void Widget::showMediaMetadata() {
    // 获取所有元数据
    QString metaStr;
    metaStr += QString("标题: %1\n").arg(libvlc_media_get_meta(m_vlcMedia, libvlc_meta_Title));
    metaStr += QString("作者: %1\n").arg(libvlc_media_get_meta(m_vlcMedia, libvlc_meta_Artist));
    metaStr += QString("时长: %1秒\n").arg(libvlc_media_get_duration(m_vlcMedia) / 1000);

    // 获取分辨率
    unsigned width = 0, height = 0;
    libvlc_video_get_size(m_vlcMediaPlayer, 0, &width, &height);
    metaStr += QString("分辨率: %1x%2\n").arg(width).arg(height);

    // 其他元数据
//    const char* metas[] = { "Album", "Date", "Genre", "Copyright" };
//    for (const char* meta : metas) {
//        const char* val = libvlc_media_get_meta(m_vlcMedia, libvlc_meta_t(meta));
//        if (val) metaStr += QString("%1: %2\n").arg(meta).arg(val);
//    }

    // 显示到控件
    ui->textMetaData->setPlainText(metaStr);
}


void Widget::setVideoAspectRatio(bool aspectRatio)
{
    if (m_vlcMediaPlayer)
    {
        QString ratio = QString("%1:%2").arg(ui->widgetRender->width()).arg(ui->widgetRender->height());
        libvlc_video_set_aspect_ratio(m_vlcMediaPlayer, aspectRatio ? NULL : ratio.toUtf8().data());
    }
}

void Widget::initSpeedComboBox() {
    // 清空现有选项
    ui->comboBoxRate->clear();

    // 添加选项（文本显示 + 实际数值）
    QMap<double, QString> speedOptions = {
        {0.5, "0.5x"}, {1.0, "1.0x"}, {1.5, "1.5x"}, {2.0, "2.0x"}
    };

    for (auto it = speedOptions.begin(); it != speedOptions.end(); ++it) {
        ui->comboBoxRate->addItem(it.value(), it.key());
    }

    // 设置默认值（1.0x）
    m_defaultIndex = ui->comboBoxRate->findData(1.0);
    ui->comboBoxRate->setCurrentIndex(m_defaultIndex);

    // 连接信号槽
    connect(ui->comboBoxRate, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, [&](int index){
            double speed = ui->comboBoxRate->itemData(index).toDouble();
            if (m_vlcMediaPlayer) {
                libvlc_media_player_set_rate(m_vlcMediaPlayer, speed);
            }
    });
}
